package ema.tpjee.banking.controler;

import java.io.IOException;
import java.util.List;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import ema.tpjee.banking.dao.BankDao;
import ema.tpjee.banking.dao.CustomerDao;
import ema.tpjee.banking.dao.CityDao;
import ema.tpjee.banking.model.Bank;
import ema.tpjee.banking.model.City;
import ema.tpjee.banking.model.Customer;
import ema.tpjee.banking.session.BankingSession;
import ema.tpjee.utils.ServletUtils;
import ema.tpjee.utils.local.AppLocator;

/**
 * Servlet implementation class for Servlet: ClientControler
 * 
 */
public class ClientControler extends javax.servlet.http.HttpServlet implements
		javax.servlet.Servlet {
	static final long serialVersionUID = 1L;

	
	private void getCities(HttpServletRequest request,BankingSession session){
		List<City> cities = session.getCityDao().getList();
		request.getSession().setAttribute("cities",cities);	//pour interface avec les jsp
	}
	
	
	/**
	 * reconstituer le nouvel objet � partir des param�tres de la request les
	 * frameworks le font par introspection
	 * 
	 * @param request
	 * @return
	 */
	private Customer formValue(HttpServletRequest request,BankingSession session) {
			Customer result = new Customer();
		int cid = -1;
		try {
			cid = Integer.parseInt(request.getParameter("commune"));
		} catch (Exception e) {
			System.out.println("no cust city");
		}
		result.setId(Integer.parseInt(request.getParameter("id")));
		result.setName(request.getParameter("name"));
		result.setForName(request.getParameter("forName"));
		result.setAddress(request.getParameter("address"));
		result.setZipCode(request.getParameter("zipCode"));
		
		try {
		Bank bank = session.getBankDao().find(Integer.parseInt(request.getParameter("bank")));
		result.setBank(bank);
		} catch (Exception e) {
			System.out.println("err cust bank");
		}
		

		if (cid!=-1){
			City city = session.getCityDao().find(cid);
		    result.setCity(city);
		}

		return result;
	}
	
	
	/*
	 * (non-Java-doc)
	 * 
	 * @see javax.servlet.http.HttpServlet#doGet(HttpServletRequest request,
	 *      HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		
		BankingSession bsession = (BankingSession) request.getSession().getAttribute("sessionbean");
		if (bsession==null){
			getServletContext().getRequestDispatcher("/nosession.jsp").forward(request, response);
			return;
		}			
		
		ServletUtils.debugRequestParameters(this.getClass(), request);
		ServletUtils.debugSessionAttributes(this.getClass(), request);
		
		//String referer = request.getHeader("referer");
		//referer= referer.substring(referer.lastIndexOf("/")+1);
		String formbeanclassname= request.getParameter("formbeanclass");
		System.out.println("formbeanclass = " + formbeanclassname);
		// �tape 1 d�coder les �v�nements depuis la request

		String page_ = request.getParameter("page");
		String cmd = request.getParameter("cmd");

		System.out.println("cmd = " + cmd);

		// �tape 2 reconstituer l'objet de domaine depuis la request

		Customer oldBean = null; 
		// l'ancienne valeur
		Customer newBean = null; 
		// la nouvelle valeur, celle qui sera pr�sent�e � la vue
		
		Customer formBean = null;
		
		if (Customer.class.getName().equals(formbeanclassname)) 
			formBean = formValue(request,bsession); 
	
		// la valeur re�ue par la requ�te (avant validation)

		// �tape 3 retrouver la valeur de l'objet du domaine avant l'action
		
		if (formBean != null)
			oldBean = bsession.getCustomerDao().find(formBean.getBank(),formBean.getId()); 
		// de pr�f�rence dans la couche de persistance
		else
			oldBean = (Customer) request.getSession().getAttribute("currentcustomer");
		// sinon dans notre contexte web

		Bank currentBank = (Bank) request.getSession().getAttribute("currentbank");

		if (oldBean == null || !bsession.getBankDao().isSame(oldBean.getBank(), currentBank))//s'il n'y avait pas de bean courant, ou si le bean courant appartenait à un autre parent
			oldBean = bsession.getCustomerDao().first(currentBank); 
		// par d�faut, prendre le premier de la liste

		// �tape 4
		// 4a appliquer les RG
		// 4b g�rer les erreurs de validation, g�n�rer les messages d'erreur
		// 4c appliquer la nouvelle valeur sur le mod�le si ok
		// 4d pr�parer l'objet valid� et modifi� ou invalid� pour correction, �
		// pr�senter dans la vue (newbean)
try {
	

		if ("editer".equals(cmd))
			newBean = oldBean;
		else if ("suivant".equals(cmd))
			newBean = bsession.getCustomerDao().next(currentBank,oldBean);
		else if ("precedent".equals(cmd))
			newBean = bsession.getCustomerDao().prior(currentBank,oldBean);
		else if ("dupliquer".equals(cmd))
			newBean = bsession.getCustomerDao().clone(currentBank,oldBean);
		else if ("supprimer".equals(cmd))
			newBean = bsession.getCustomerDao().delete(currentBank,oldBean);
		else if ("ajouter".equals(cmd))
			newBean = bsession.getCustomerDao().create(currentBank);
		else if ("annuler".equals(cmd))
			newBean = oldBean;
		else if ("modifier".equals(cmd))
			newBean = doModify(request, bsession, formBean);
		else if ("foobar".equals(cmd))
			newBean = foobar(request, bsession, formBean);

} catch (Exception e) {
	getServletContext().getRequestDispatcher("/dataerror.jsp").forward(request, response);
	return;
}
		
		
		
		if (newBean != null)
			request.getSession().setAttribute("currentcustomer", newBean); //pour interface avec les jsp
		else
			request.getSession().setAttribute("currentcustomer", oldBean);
		request.getSession().setAttribute("customers", bsession.getCustomerDao().getList(currentBank));// reverseListBank());

		// �tape 5 appliquer les r�gles de navigation, diriger la requ�te vers la vue
		String fw = null;

		
		// les controleurs ne se connaissent pas entre eux. On passe par l'uri. On
		// utilise le contexte de session ou de requ�te pour passer les param�tres
		if (page_ != null && !"null".equals(page_))
			fw = "/pages/" + page_ + ".jsp";
		else
			fw = "/pages/client.jsp";

		// �tape 6 faire suivre l'ex�cution vers la vue
		System.out.println("forwarding to: " + fw);
		getServletContext().getRequestDispatcher(fw).forward(request, response);
	}	
	
	
	
	
	/**
	 * modifier l'objet au sein du mod�le apr�s validation
	 * 
	 * @param request
	 * @param b
	 * @return
	 */
	private Customer doModify(HttpServletRequest request, BankingSession session,Customer c) {
		Customer result = null;
		try {
			validate(c,session);
			result = session.getCustomerDao().merge(c); 
			// le mod�le est mis � jour, si pas d'exception
		} catch (Exception e) {
			result = c; 
			// formBean is returned but not modified in persistence layer
			System.out.println("error " + e.getMessage());
			request.setAttribute("error", "erreur " + e.getMessage());
		}
		return result;
	}

	/**
	 * validation x On souhaiterait une hi�rarchie d'exceptions
	 * 
	 * @param b
	 */
	private void validate(Customer c,BankingSession session) {
		if (c.getName().contains("supercrash")
				|| c.getName().contains("forbidden"))
			throw new RuntimeException("the name is forbidden!");
	}


	
	private Customer foobar(HttpServletRequest request, BankingSession session, Customer formBean) {
		// TODO Auto-generated method stub
		return null;
	}

	

	/*
	 * (non-Java-doc)
	 * 
	 * @see javax.servlet.http.HttpServlet#doPost(HttpServletRequest request,
	 *      HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		doGet(request, response);
	}
}